/*
 * SelectInterrupter.h
 *
 *  Created on: Jun 5, 2013
 *      Author: Lucifer
 */

#ifndef SELECTINTERRUPTER2_H_
#define SELECTINTERRUPTER2_H_

namespace BFX
{

class SelectInterrupter;

#if defined(_WIN32) || defined(__CYGWIN__)

////////////////////////////////////////////////////////////////////////////////

/**
 * This class uses to interrupt the select function.
 */
class SelectInterrupter
{
public:
	/**
	 * Initializes a new instance of BFX::SelectInterrupter.
	 */
	SelectInterrupter();

	/**
	 * Destroys the BFX::SelectInterrupter instance.
	 */
	virtual ~SelectInterrupter();

	/**
	 * Interrupt the select call.
	 * A single byte may be written to this to wake up the select which is waiting for the other end to become readable.
	 */
	void Interrupt();

	/**
	 * Reset the select interrupt.
	 * a single byte will be written on the other end of the connection and this descriptor will become readable.
	 *
	 * @return True if the call was interrupted.
	 */
	bool Reset();

	/**
	 * Gets the file descriptor uses to interrupt a select call.
	 * @return
	 */
	SOCKET GetFileDescriptor() const
	{
		return m_fdRecv;
	}

private:
	// Forbidden copy constructor and assignment operator.
	SelectInterrupter(const SelectInterrupter&);
	SelectInterrupter& operator = (const SelectInterrupter&);

private:
	SOCKET	m_fdRecv;
	SOCKET	m_fdSend;
};

#elif defined(BFX_IO_HAS_EVENTFD)

#else

class SelectInterrupter
{
public:
	void Interrupt() {}
	bool Reset() { return false; }
	SOCKET GetFileDescriptor() const { return INVALID_SOCKET; }
};

#endif


} /* namespace BFX */
#endif /* SELECTINTERRUPTER2_H_ */
